package br.com.vpsa.previdordevendas.model.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import br.com.vpsa.previdordevendas.model.entity.PrevisaoManual;
import br.com.vpsa.previdordevendas.model.pojo.FaturamentoAnual;
import br.com.vpsa.previdordevendas.model.service.PrevisaoManualService;
import br.com.vpsa.previdordevendas.model.util.CalendarUtils;
import br.com.vpsa.previdordevendas.model.util.MoedaUtil;

@Service
public class PrevisaoManualServiceImpl implements PrevisaoManualService
{

    @PersistenceContext
    private EntityManager em;
	
	@Override
	public List<FaturamentoAnual> gerarPrevisaoAnual(String base, long idEntidade) 
	{
		List<FaturamentoAnual> faturamentosAnuais = new ArrayList<FaturamentoAnual>();
		List<PrevisaoManual> previsoes = listarPrevisoes(base, idEntidade);
		
		int anoAtual = CalendarUtils.getAnoAtual();
		
		for( int ano=anoAtual ; ano <= anoAtual + CalendarUtils.ANOS_FUTUROS ; ano++ )
		{
			FaturamentoAnual faturamentoAnual = new FaturamentoAnual();
			faturamentoAnual.setAno(ano);
			faturamentoAnual.setJaneiro(getValor(previsoes,ano, Calendar.JANUARY));
			faturamentoAnual.setFevereiro(getValor(previsoes,ano, Calendar.FEBRUARY));
			faturamentoAnual.setMarco(getValor(previsoes,ano, Calendar.MARCH));
			faturamentoAnual.setAbril(getValor(previsoes,ano, Calendar.APRIL));
			faturamentoAnual.setMaio(getValor(previsoes,ano, Calendar.MAY));
			faturamentoAnual.setJunho(getValor(previsoes,ano, Calendar.JUNE));
			faturamentoAnual.setJulho(getValor(previsoes,ano, Calendar.JULY));
			faturamentoAnual.setAgosto(getValor(previsoes,ano, Calendar.AUGUST));
			faturamentoAnual.setSetembro(getValor(previsoes,ano, Calendar.SEPTEMBER));
			faturamentoAnual.setOutubro(getValor(previsoes,ano, Calendar.OCTOBER));
			faturamentoAnual.setNovembro(getValor(previsoes,ano, Calendar.NOVEMBER));
			faturamentoAnual.setDezembro(getValor(previsoes,ano, Calendar.DECEMBER));
			
			faturamentosAnuais.add(faturamentoAnual);
		}
		
		return faturamentosAnuais;
	}

	private String getValor(List<PrevisaoManual> previsoes, int ano, int mes) 
	{
		PrevisaoManual previsaoManual = PrevisaoManual.find(previsoes, mes, ano);
		
		String result = null;
		
		if( previsaoManual != null ){
			result = MoedaUtil.convert( previsaoManual.getValorTotal() );
		}
		
		return result;
	}

	private List<PrevisaoManual> listarPrevisoes(String base, long idEntidade) 
	{
		String hql = "FROM PrevisaoManual p where p.base = :base and p.idEntidade = :entidade order by p.ano, p.mes asc";
		
		TypedQuery<PrevisaoManual> query = em.createQuery(hql,PrevisaoManual.class);
		query.setParameter("base", base);
		query.setParameter("entidade",idEntidade);
		
	   return query.getResultList();		

	}

	@Override
	@Transactional
	public void salvarPrevisao(String base, long idEntidade, List<FaturamentoAnual> faturamentosAnuais) 
	{
		apagarPrevisoesManuais(base, idEntidade);
		
		for( FaturamentoAnual faturamentoAnual : faturamentosAnuais )
		{
			int mes = 0;
			
			for( BigDecimal valor : faturamentoAnual.getFaturamentoMensal() )
			{
				PrevisaoManual previsaoManual = new PrevisaoManual(idEntidade, faturamentoAnual.getAno(), mes++, valor, base );

				if( valor != null ){
					em.persist(previsaoManual);
				}
			}
		}
		
	}

	@Transactional
	public void apagarPrevisoesManuais(String base, long idEntidade) 
	{
		String hql = "delete from PrevisaoManual p where p.base = :base and p.idEntidade = :entidade";
		
		Query query = em.createQuery(hql);
		query.setParameter("base", base);
		query.setParameter("entidade",idEntidade);
		
		query.executeUpdate();
	}

	@Override
	public List<BigDecimal> listarPrevisaoManual(String base, Long idEntidade, int ano)
	{
		String hql = "select new br.com.vpsa.previdordevendas.model.entity.PrevisaoManual( p.ano, p.mes, sum(p.valorTotal)  ) from PrevisaoManual p " +
				" where p.ano = :ano and p.base = :base ";
		
		if( idEntidade != null ){
			hql += " and p.idEntidade = :entidade ";
		}
		
		hql += " group by p.ano, p.mes order by p.mes";
		
		TypedQuery<PrevisaoManual> query = em.createQuery(hql, PrevisaoManual.class);
		query.setParameter("ano", ano);
		query.setParameter("base", base);
		
		if( idEntidade != null ){
			query.setParameter("entidade", idEntidade);
		}
		
		List<PrevisaoManual> previsoesManuais = query.getResultList();
		List<BigDecimal> valores = new ArrayList<BigDecimal>();
		
		for( int mes : CalendarUtils.meses )
		{
			PrevisaoManual previsaoManual = PrevisaoManual.find(previsoesManuais, mes, ano);
			BigDecimal valor = null;
			
			if( previsaoManual != null ){
				valor = previsaoManual.getValorTotal();
			}
			
			valores.add(valor);
		}
		
		return valores;
	}
	
	
	
}
